﻿using DevExpress.XtraEditors.Repository;
using DevTeam;
using Fatura;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.ServiceModel;
using System.Linq;


namespace Fatura
{


    public partial class FaturaKaydet : XImportWizard
    {
        public FaturaKaydet()
        {
            InitializeComponent();
            pe = new ParseExcel();
        }

        DataSet dsData = null;
        ParseExcel pe;
        private void Form1_Load(object sender, EventArgs e)
        {            
            this.FileDone += Form1_FileDone;
            this.ProcessDone += Form1_ProcessDone;
            this.ProcessStart += Form1_ProcessStart;

            dsData = ExecuteDataSet("FT_GetInvoice", null, null, null);
            gvMaster.Init(dsData.Tables[0]);
            gvMaster.AddDetailGrid(gvDetail, "InvoiceHeaderId");

            gvMaster.AddAutoIncrementalPK("InvoiceHeaderId");

            dtMusteri = ExecuteDataTable("FT_GetCustomer");

            RepositoryItemGridLookUpEdit riMusteri = RepositoryManager.GetGLESablon(dtMusteri, "Name", "CustomerId");

            gleSirket.Edit.Assign(RepositoryManager.Get("SirketId"));
            gleMusteri.Edit.Assign(riMusteri);

            gvMaster.MakeColumnInvisible("CustomerId");

            gvDetail.AddSummary("Quantity", "UnitPrice", "TotalValue");
            
            btnSave.ItemClick += btnSave_ItemClick;
            gleMusteri.EditValueChanged += gleMusteri_EditValueChanged;
            gleSirket.EditValueChanged += gleSirket_EditValueChanged;
        }

        void gleSirket_EditValueChanged(object sender, EventArgs e)
        {
            gleMusteri.Enabled = gleSirket.EditValue.ToInt() > 0;
            gleMusteri.EditValue = null;

            DataTable dtSirket = (DataTable)((RepositoryItemGridLookUpEdit)gleSirket.Edit).DataSource;
            string Sirket = dtSirket.Select("SirketId=" + gleSirket.EditValue)[0]["Name"].ToStr();

            dtMusteri.DefaultView.RowFilter = "Sirket = '" + Sirket + "'";
            gleMusteri.Edit.Assign(GetCustomGLE(dtMusteri, "Name", "CustomerId"));
        }

        DataTable dtSablon, dtMusteri;
        void gleMusteri_EditValueChanged(object sender, EventArgs e)
        {
            dtSablon = ExecuteDataTable("FT_GetSablon", gleSirket.EditValue, gleMusteri.EditValue); 

            if (dtSablon.Rows.Count == 0)
                ShowErrorMessage("Bu müşteriye ait şablon bulunamadı!");

            bbiOnizle.Enabled = btnSave.Enabled = btnProcessFile.Enabled = dtSablon.Rows.Count > 0;       
        }

        void btnSave_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            gvMaster.EndEditing();
            gvDetail.EndEditing();
            foreach (DataRow drMaster in gvMaster.Update().Select("NewId is not null"))
            {
                dsData.Tables[0].Select("InvoiceHeaderId =" + drMaster["InvoiceHeaderId"])[0]["InvoiceHeaderId"] = drMaster["NewId"];
                foreach (DataRow drDetail in dsData.Tables[1].Select("InvoiceHeaderId =" + drMaster["InvoiceHeaderId"]))
                    drDetail["InvoiceHeaderId"] = drMaster["NewId"];
            }

            gvDetail.Update();
            //string xmlInvoice = gvMaster.Serialize();
            //string xmlInvoiceLines = gvDetail.Serialize();

            //ExecuteNonQuery("FT_InsFatura", gleSirket.EditValue, gleMusteri.EditValue, xmlInvoice, xmlInvoiceLines, WhoAmI);
        }

        void Form1_ProcessStart()
        {
            ds = new DataSet();
        }

        void Form1_ProcessDone()
        {
            DataTable dt = ds.Tables[0];
            bbiOnizle.PerformClick();
        }

        DataSet ds;
        void Form1_FileDone(DataSet Data, string FileName)
        {
            ds = Data;
        }

        private void bbiOnizle_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            //BasicHttpBinding binding = new BasicHttpBinding();
            //binding.MaxReceivedMessageSize = 65536000;            
            //KarbelFatura.FaturaServicesSoapClient kf = new KarbelFatura.FaturaServicesSoapClient();
            //kf.Endpoint.Binding = binding;

            //DateTime SonCekimTarihi = DateTime.Now.AddDays(-1);
            //string FaturaNo = "H5.1195A";
            //DataSet dsFatura = kf.IhracatFaturalariniAl("karbel", "karbel",FaturaNo, SonCekimTarihi);

            if (ds == null)
            {
                ShowErrorMessage("Lütfen fatura dosyasını okutun!");
                return;
            }

            if (gleSirket.EditValue.ToInt() == 3)
                InitFromErsurExcel();
            else
                InitFromExcel();

            gvMaster.BestFitColumns();
            gvDetail.BestFitColumns();
        }

        private void InitFromExcel()
        {
            //Fatura başlık bilgilerini gride doldurma
            DataTable dtInvoice = gvMaster.DataTable();
            DataColumnCollection dcInvoice = dtInvoice.Columns;
            DataRow drInvoice = dtInvoice.NewRow();

            foreach (DataRow dr in dtSablon.Select("ActionId in (1,2)"))
            {
                int Action = dr["ActionId"].ToInt();
                int Yon = dr["DirectionId"].ToInt();
                int Dur = dr["StopConditialId"].ToInt();
                string ExcelCaption = dr["ExcelCaption"].ToStr();
                string DBCaption = dr["DBCaption"].ToStr();

                string Value = "";
                if (Action == 1)
                    Value = pe.GetValue(ds.Tables[0], ExcelCaption, ParseExcel.Direction.Down);
                else if (Action == 2)
                {
                    bool stop = Dur == 2;
                    Value = pe.GetValue(ds.Tables[0], ExcelCaption, (ParseExcel.Direction)Yon, stop);
                }

                if (Value != "")
                {

                    if (DBCaption.Contains("Date"))
                        Value = DateTime.FromOADate(double.Parse(Value)).ToString("dd.MM.yyyy");

                    if (dcInvoice.Contains(DBCaption))
                        if (Value != "")
                            drInvoice[DBCaption] += Value + " ";
                }
            }

            foreach (DataRow dr in dtSablon.Select("ActionId=4"))
            {
                string ExcelCaption = dr["ExcelCaption"].ToStr();
                bool ReadRightCell = dr["ReadRightCell"].ToBool();

                DataTable dtSubTotals = pe.GetSubTotal(ds.Tables[0], ExcelCaption, ReadRightCell);
                int SubTotalIndex = 1;
                foreach (DataRow drSubTotal in dtSubTotals.Rows)
                {
                    string TotalcolumnName = (ExcelCaption.ToLower() == "total  value" ? "SubTotal" : "TotalQty") + SubTotalIndex.ToStr();
                    string DesccolumnName = (ExcelCaption.ToLower() == "total  value" ? "SubTotal" : "TotalQty") + SubTotalIndex.ToStr() + "Desc";

                    drInvoice[TotalcolumnName] = drSubTotal["Total"];
                    drInvoice[DesccolumnName] = drSubTotal["TotalDesc"];

                    SubTotalIndex++;
                }
            }

            string DovizCinsi = ds.Tables[ds.Tables.Count - 1].Rows[0]["DovizCinsi"].ToStr();
            drInvoice["Currency"] = DovizCinsi;
            drInvoice["SirketId"] = gleSirket.EditValue;
            drInvoice["CustomerId"] = gleMusteri.EditValue;

            dtInvoice.Rows.Add(drInvoice);

            //Fatura detay satırlarını gride doldurma

            DataTable dtInvoiceLines = gvDetail.DataTable();
            DataTable dtInvoiceLinesExcel = pe.GetInvoiceLines(ds.Tables[0], "Total  Value");
            DataColumnCollection dcInvoiceLines = dtInvoiceLines.Columns;

            foreach (DataRow dr in dtInvoiceLinesExcel.Rows)
            {
                DataRow drInvoiceLines = dtInvoiceLines.NewRow();
                drInvoiceLines["InvoiceHeaderId"] = drInvoice["InvoiceHeaderId"];
                foreach (DataColumn dc in dtInvoiceLinesExcel.Columns)
                {
                    string ExcelCaption = dc.ColumnName;
                    DataRow[] drDBCaption = dtSablon.Select("ActionId in (3) and ExcelCaption = '" + ExcelCaption + "'");

                    if (drDBCaption.Length > 0)
                    {
                        string DBCaption = drDBCaption[0]["DBCaption"].ToStr();
                        if (dcInvoiceLines.Contains(DBCaption))
                            if (dtInvoiceLines.Columns[DBCaption].DataType.Name == "Decimal")
                                drInvoiceLines[DBCaption] = dr[dc.ColumnName].ToDecimal();
                            else if (dr[dc.ColumnName].ToStr() != "")
                                drInvoiceLines[DBCaption] += dr[dc.ColumnName].ToStr();
                    }
                    else if (ExcelCaption == "Unit")
                        drInvoiceLines["Unit"] = dr["Unit"];
                }
                dtInvoiceLines.Rows.Add(drInvoiceLines);
            }
        }

        private void InitFromErsurExcel()
        {
            //Fatura başlık bilgilerini gride doldurma
            DataTable dtInvoice = gvMaster.DataTable();
            DataColumnCollection dcInvoice = dtInvoice.Columns;
            DataRow drInvoice = dtInvoice.NewRow();

            foreach (DataRow dr in dtSablon.Select("ActionId in (1,2)"))
            {
                int Action = dr["ActionId"].ToInt();
                int Yon = dr["DirectionId"].ToInt();
                int Dur = dr["StopConditialId"].ToInt();
                string ExcelCaption = dr["ExcelCaption"].ToStr();
                string DBCaption = dr["DBCaption"].ToStr();

                string Value = "";
                if (Action == 1)
                    Value = pe.GetValue(ds.Tables[0], ExcelCaption, ParseExcel.Direction.Down);
                else if (Action == 2)
                {
                    bool stop = Dur == 2;
                    Value = pe.GetValue(ds.Tables[0], ExcelCaption, (ParseExcel.Direction)Yon, stop);
                }

                if (Value != "")
                {

                    if (DBCaption.Contains("Date"))
                        Value = DateTime.FromOADate(double.Parse(Value)).ToString("dd.MM.yyyy");

                    if (dcInvoice.Contains(DBCaption))
                        if (Value != "")
                            drInvoice[DBCaption] += Value + " ";
                }
            }

            foreach (DataRow dr in dtSablon.Select("ActionId=4"))
            {
                string ExcelCaption = dr["ExcelCaption"].ToStr();

                DataTable dtSubTotals = GetErsurSubTotal(ds.Tables[0], ExcelCaption);
                int SubTotalIndex = 1;
                foreach (DataRow drSubTotal in dtSubTotals.Rows)
                {
                    string TotalcolumnName = (ExcelCaption.ToLower() == "total amount" ? "SubTotal" : "TotalQty") + SubTotalIndex.ToStr();
                    string DesccolumnName = (ExcelCaption.ToLower() == "total amount" ? "SubTotal" : "TotalQty") + SubTotalIndex.ToStr() + "Desc";

                    drInvoice[TotalcolumnName] = drSubTotal["Total"];
                    drInvoice[DesccolumnName] = drSubTotal["TotalDesc"];

                    SubTotalIndex++;
                }
            }
                        
            drInvoice["SirketId"] = gleSirket.EditValue;
            drInvoice["CustomerId"] = gleMusteri.EditValue;
            drInvoice["Currency"] = ErsurDegerOku("Currency");
            drInvoice["NetWeight"] = ErsurDegerOku("Net Weight");
            drInvoice["GrossWeight"] = ErsurDegerOku("Gross Weight");
            drInvoice["TotalCarton"] = ErsurDegerOku("Total Carton");
            drInvoice["Customer"] = ErsurMusteriOku("* Invoice To");
            drInvoice["InvoiceDate"] = ErsurFaturaTarihiOku();

            drInvoice["InvoiceAddress"] = ErsurAdresAl("* Invoice To", "EORI");
            drInvoice["Notify"] = ErsurAdresAl("* Notify", "EORI");
            drInvoice["Exporter"] = ErsurAdresAl("* Exporter", "Vat No");
            drInvoice["Manufacturer"] = ErsurAdresAl("* Manufacturer", "Vat No");



            dtInvoice.Rows.Add(drInvoice);

            //Fatura detay satırlarını gride doldurma

            DataTable dtInvoiceLines = gvDetail.DataTable();
            DataTable dtInvoiceLinesExcel = GetErsurInvoiceLines();
            DataColumnCollection dcInvoiceLines = dtInvoiceLines.Columns;

            foreach (DataRow dr in dtInvoiceLinesExcel.Rows)
            {
                DataRow drInvoiceLines = dtInvoiceLines.NewRow();
                drInvoiceLines["InvoiceHeaderId"] = drInvoice["InvoiceHeaderId"];
                foreach (DataColumn dc in dtInvoiceLinesExcel.Columns)
                {
                    string ExcelCaption = dc.ColumnName;
                    DataRow[] drDBCaption = dtSablon.Select("ActionId in (3) and ExcelCaption = '" + ExcelCaption + "'");

                    if (drDBCaption.Length > 0)
                    {
                        string DBCaption = drDBCaption[0]["DBCaption"].ToStr();
                        if (dcInvoiceLines.Contains(DBCaption))
                            if (dtInvoiceLines.Columns[DBCaption].DataType.Name == "Decimal")
                                drInvoiceLines[DBCaption] = dr[dc.ColumnName].ToDecimal();
                            else if (dr[dc.ColumnName].ToStr() != "")
                                drInvoiceLines[DBCaption] += dr[dc.ColumnName].ToStr();
                    }                   
                }
                dtInvoiceLines.Rows.Add(drInvoiceLines);
            }
        }

        private object ErsurFaturaTarihiOku()
        {
            DataTable dt = ds.Tables[0];
            Point pt = pe.FindPositionByValue(dt, "Invoice Date");

            string Value = "";

            for (int dc = pt.Y; dc > 0; dc--)
            {
                string cellValue = dt.Rows[pt.X + 1][dc].ToStr();
                if (cellValue != "")
                {
                    Value = DateTime.FromOADate(double.Parse(cellValue)).ToString("dd.MM.yyyy");
                    break;
                }
            }
            return Value;
        }

        private string ErsurMusteriOku(string Caption)
        {
            DataTable dt = ds.Tables[0];
            Point pt = pe.FindPositionByValue(dt, Caption);
            int ColumnIndex = 0;
            string Value = "";

            for (int dc = pt.Y + 1; dc < dt.Columns.Count; dc++)
            {
                if (dt.Rows[pt.X][dc].ToStr() != "")
                {
                    ColumnIndex = dc;
                    break;
                }
            }

            for (int dr = pt.X; dr < dt.Rows.Count; dr++)
            {
                string cellValue = dt.Rows[dr][ColumnIndex].ToStr();
                if (cellValue != "")
                {
                    Value = cellValue;
                    break;
                }
            }

            return Value;
        }

        private string ErsurAdresAl(string Caption,string Destination)
        {
            DataTable dt = ds.Tables[0];
            Point pt = pe.FindPositionByValue(dt, Caption);
            int ColumnIndex = 0;
            string Value = "";

            for (int dc = pt.Y + 1; dc < dt.Columns.Count; dc++)
            {
                if (dt.Rows[pt.X][dc].ToStr() != "")
                {
                    ColumnIndex = dc;
                    break;
                }
            }

            for (int dr = pt.X; dr < dt.Rows.Count; dr++)
            {
                string cellValue= dt.Rows[dr][ColumnIndex].ToStr();
                if (cellValue != "")
                    Value += cellValue + " ";
                if (cellValue.StartsWith(Destination))
                    break;
            }

            return Value;
        }

        private DataTable GetErsurSubTotal(DataTable dt, string Value)
        {
            DataTable DtRetreived = new DataTable();
            DtRetreived.Columns.Add("Total", typeof(decimal));
            DtRetreived.Columns.Add("TotalDesc", typeof(string));

            Point pt = pe.FindPositionByValue(dt, Value);

            bool IsEndOfInvoiceLines = false;
            for (int dr = pt.X + 2; dr < dt.Rows.Count; dr++)
            {
                decimal value = Math.Abs(dt.Rows[dr][pt.Y].ToDecimal());
                if (value > 0 && !IsEndOfInvoiceLines)
                    continue;
                IsEndOfInvoiceLines = true;

                if (value > 0)
                {
                    int columnIndex = pt.Y;
                    string caption = "";
                    if (Value == "Total Amount")
                        for (int i = pt.Y - 1; i > 0; i--)
                        {
                            caption = dt.Rows[dr][i].ToStr();
                            if (caption != "")
                            {
                                if (caption.ToLower() == "kgs")
                                    caption = "";
                                break;
                            }
                        }
                    else
                        for (int i = pt.Y + 1; i < dt.Columns.Count; i++)
                        {
                            caption = dt.Rows[dr][i].ToStr();
                            if (caption != "" || i - pt.Y > 2)
                                break;
                        }

                    DtRetreived.Rows.Add(value, caption);
                }
            }

            return DtRetreived;
        }

        private string ErsurDegerOku(string Caption)
        {
            Point pt = pe.FindPositionByValue(ds.Tables[0], Caption);
            string Value = ds.Tables[0].Rows[pt.X + 2][pt.Y].ToStr();
            return Value;
        }

        private DataTable GetErsurInvoiceLines()
        {
            DataTable DtRetreived = new DataTable();
            DataTable dt = ds.Tables[0];

            Point pt = pe.FindPositionByValue(dt, "Total Amount");
            List<string> Captions = new List<string>();
            int FirstColumnIndex = 0;

            for (int dc = pt.Y; dc >= 0; dc--)
            {
                string CellValue = dt.Rows[pt.X][dc].ToStr();
                if (CellValue != "")
                    Captions.Add(CellValue);                
                FirstColumnIndex = dc;
            }

            foreach (string Caption in Captions.Reverse<string>())
            {
                DtRetreived.Columns.Add(Caption);
            }

            bool OuterBreak = false;
            for (int dr = pt.X + 2; dr < dt.Rows.Count; dr++)
            {
                DataRow newRow = DtRetreived.NewRow();
                int ColumnIndex=-1;
                for (int dc = FirstColumnIndex; dc <= pt.Y; dc++)
                {
                    if (dt.Rows[pt.X][dc].ToStr() == "")
                        continue;
                    else
                        ColumnIndex++;

                    string ColumnName = DtRetreived.Columns[ColumnIndex].ColumnName;
                    string CellValue = dt.Rows[dr][dc].ToStr();

                    if (ColumnName.ToLower() == "total amount" && CellValue == "")
                    {
                        OuterBreak = true;
                        break;
                    }
                    newRow[ColumnName] = dt.Rows[dr][dc].ToStr();
                }
                if (OuterBreak)
                    break;

                DtRetreived.Rows.Add(newRow);
            }

            return DtRetreived;
        }
    }
}
